www.gusucode.com > VC++ Http代理服务器实例-源码程序 > VC++ Http代理服务器实例-源码程序/code/HTTP proxy/ProxyServer1.cpp
//Download by http://www.NewXing.com // ProxyServer1.cpp: implementation of the CProxyServer class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ProxyServer.h" #include "ProxyServer1.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CProxyServer::CProxyServer() { } CProxyServer::~CProxyServer() { } UINT CProxyServer::ListenThread(LPVOID lpVoid) { int iRet, addrLen; sockaddr_in addr, addrAccept; SOCKET sckListen, sckAccept; char pszMsg[512]; int nErrCount; CProxyServer* pServer = (CProxyServer*)lpVoid; pServer->OUTPUT(pServer,"going to create socket.\r\n"); sckListen = socket(AF_INET, SOCK_STREAM, 0); if(sckListen == INVALID_SOCKET) { sprintf(pszMsg, "INVALID_SOCKET, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); return 0; } pServer->OUTPUT(pServer,"Listening socket created successfully.\r\n"); iRet = gethostname(pszMsg, 256); if(iRet) { sprintf(pszMsg, "Error occur when gethostname(), WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); return 0; } hostent* pEnt = gethostbyname(pszMsg); if(!pEnt) { sprintf(pszMsg, "Error occur when gethostbyname(), WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); return 0; } memcpy(&(addr.sin_addr), pEnt->h_addr, pEnt->h_length); addr.sin_family = AF_INET; addr.sin_port = htons(pServer->m_Info.nPort); pServer->m_Info.strLocalAddr.Format("%s", inet_ntoa(addr.sin_addr)); iRet = bind(sckListen, (const sockaddr*)&addr, sizeof(addr)); if(iRet==SOCKET_ERROR) { sprintf(pszMsg, "SOCKET_ERROR, WSAGetLastError()=%d", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); return 0; } nErrCount = 0; pServer->OUTPUT(pServer,"Listening...\r\n"); iRet = listen(sckListen, SOMAXCONN); if(iRet==SOCKET_ERROR) { sprintf(pszMsg, "INVALID_SOCKET, WSAGetLastError()=%d", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); nErrCount++; if(nErrCount>=10) { sprintf(pszMsg, "nErrCount>=10, listening thread terminated.\r\n"); return 0; } } nErrCount = 0; while(1) { addrLen = sizeof(addrAccept); sckAccept = accept(sckListen, (struct sockaddr*)&addrAccept, &addrLen); if(sckAccept==INVALID_SOCKET) { sprintf(pszMsg, "accept()=SOCKET_ERROR, WSAGetLastError()=%d", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); return 0; } pServer->OUTPUT(pServer,"One client accepted successfully.\r\n"); pServer->pWorkParam = new WORKPARAM; pServer->pWorkParam->sckClient = sckAccept; pServer->pWorkParam->addr = addrAccept; AfxBeginThread(WorkingThread, (LPVOID)pServer, THREAD_PRIORITY_BELOW_NORMAL); } return 0; } void CProxyServer::OUTPUT(CProxyServer* pServer,LPCTSTR pszMsg) { SendMessage(pServer->m_Info.hWnd, AGM_OUTPUT, 0, (LPARAM)pszMsg); } UINT CProxyServer::WorkingThread(LPVOID lpVoid) { CProxyServer* pServer = (CProxyServer*)lpVoid; WORKPARAM * pThreadParam = pServer->pWorkParam; DWORD dwRet, dwTotal, dwSize; sockaddr_in addrProxy2nd; SOCKET sckClient; REQUESTHEADER requestHeader; HTTPHEADER httpHeader; FILE* pFileContent; int iRet, i; char content[512]; char buf[BUFFER_SIZE]; char pszMsg[1024]; char pszCode[256]; dwRet = WaitForSingleObject(pServer->m_hConnectionCount, INFINITE); if(pServer->m_nConnectionCount >= 12) { ReleaseSemaphore(pServer->m_hConnectionCount, 1, NULL); pServer->OUTPUT(pServer,"Too many connections, limit reached\r\n"); strcpy(buf, "HTTP/1.1 431 Too many connections, limit reached\r\n"); send(pThreadParam->sckClient , buf, strlen(buf), 0); strcpy(buf, "Proxy-agent: My-PersonalProxy/1.0\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); strcpy(buf, "Content-type: text/html\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); pFileContent = fopen("ProxyServer\\authorizationrequired.html", "rb"); dwSize = _filelength(_fileno(pFileContent)); sprintf(buf, "Content-length: %d\r\n", dwSize); send(pThreadParam->sckClient, buf, strlen(buf), 0); strcpy(buf, "\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); while(!feof(pFileContent)) { dwSize = fread(buf, 1, BUFFER_SIZE, pFileContent); send(pThreadParam->sckClient, buf, dwSize, 0); } closesocket(pThreadParam->sckClient); fclose(pFileContent); delete pThreadParam; return 0; } pServer->m_nConnectionCount++; ReleaseSemaphore(pServer->m_hConnectionCount, 1, NULL); while(1) { iRet = pServer->RecvRequest(pServer,pThreadParam->sckClient, buf, BUFFER_SIZE-1, &requestHeader); if(iRet==SOCKET_ERROR) { sprintf(pszMsg, "RecvRequest()=SOCKET_ERROR, WSAGetLastError()=%d", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); WaitForSingleObject(pServer->m_hConnectionCount, INFINITE); pServer->m_nConnectionCount--; ReleaseSemaphore(pServer->m_hConnectionCount, 1, NULL); delete pThreadParam; return 0; } dwTotal = iRet; for(i=0; i<pServer->m_nRefused; i++) { if(pServer->m_ulIpRefused[i]==pThreadParam->addr.sin_addr.S_un.S_addr) { pServer->OUTPUT(pServer,"refused ip:"); sprintf(content, "\t%d.%d.%d.%d\r\n", pThreadParam->addr.sin_addr.S_un.S_un_b.s_b1, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b2, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b3, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b4); pServer->OUTPUT(pServer,content); strcpy(buf, "HTTP/1.1 432 Ip refused\r\n"); send(pThreadParam->sckClient , buf, strlen(buf), 0); strcpy(buf, "Proxy-agent: Ag-PersonalProxy/1.0\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); strcpy(buf, "Content-type: text/html\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); pFileContent = fopen("ProxyServer\\notification.html", "rb"); dwSize = _filelength(_fileno(pFileContent)); sprintf(buf, "Content-length: %d\r\n", dwSize); send(pThreadParam->sckClient, buf, strlen(buf), 0); strcpy(buf, "\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); dwSize = fread(buf, 1, BUFFER_SIZE, pFileContent); buf[dwSize] = NULL; sprintf(content, buf, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b1, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b2, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b3, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b4); send(pThreadParam->sckClient, content, strlen(content), 0); closesocket(pThreadParam->sckClient); fclose(pFileContent); goto _ThreadExit; } } if(requestHeader.dwFlag & REQUEST_UNAUTHORIZED) { pServer->OUTPUT(pServer,"HTTP/1.1 407 Proxy authorization required agproxy."); sprintf(content, "\t%s\t%d.%d.%d.%d\r\n", requestHeader.pszUserPass, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b1, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b2, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b3, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b4); pServer->OUTPUT(pServer,content); //HTTP/1.0 407 Proxy authorization required strcpy(buf, "HTTP/1.1 407 Proxy authorization required\r\n"); send(pThreadParam->sckClient , buf, strlen(buf), 0); strcpy(buf, "Proxy-agent: Ag-PersonalProxy/1.0\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); strcpy(buf, "Content-type: image/jpeg\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); strcpy(buf, "Proxy-authenticate: basic realm=\"JutAg\"\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); pFileContent = fopen("ProxyServer\\Authorization.jpg", "rb"); dwSize = _filelength(_fileno(pFileContent)); sprintf(buf, "Content-length: %d\r\n", dwSize); send(pThreadParam->sckClient, buf, strlen(buf), 0); strcpy(buf, "\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0); while(!feof(pFileContent)) { dwSize = fread(buf, 1, BUFFER_SIZE, pFileContent); send(pThreadParam->sckClient, buf, dwSize, 0); } fclose(pFileContent); continue; } break; } if(strstr(buf, "POST")) { pServer->OUTPUT(pServer,buf); pServer->OUTPUT(pServer,"\r\n"); } else { strncpy(content, buf, strstr(buf, "\r\n")-buf+2); content[strstr(buf, "\r\n")-buf] = NULL; pServer->OUTPUT(pServer,content); } sprintf(content, "\t%d.%d.%d.%d\r\n", pThreadParam->addr.sin_addr.S_un.S_un_b.s_b1, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b2, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b3, pThreadParam->addr.sin_addr.S_un.S_un_b.s_b4); pServer->OUTPUT(pServer,content); if(requestHeader.dwFlag & VIRTUAL_RESOURCE) { pServer->HttpService(pServer,requestHeader.pszUrl, pThreadParam->sckClient, buf, &requestHeader); goto _ThreadExit; } pServer->OUTPUT(pServer,"Connecting to the second proxy.\r\n"); addrProxy2nd.sin_family = AF_INET; addrProxy2nd.sin_port = htons(pServer->m_Info.nPort2nd); addrProxy2nd.sin_addr.s_addr = inet_addr(pServer->m_Info.strProxyAddr); sckClient = socket(AF_INET, SOCK_STREAM, 0); if(sckClient==INVALID_SOCKET) { closesocket(pThreadParam->sckClient); closesocket(sckClient); sprintf(pszMsg, "socket()=INVALID_SOCKET, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); goto _ThreadExit1; } iRet = connect(sckClient, (const sockaddr*)&addrProxy2nd, sizeof(addrProxy2nd)); if(iRet==SOCKET_ERROR) { closesocket(pThreadParam->sckClient); closesocket(sckClient); sprintf(pszMsg, "connect()=SOCKET_ERROR, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); goto _ThreadExit1; } // send the data before Proxy-Authorization: send(sckClient, buf, requestHeader.pszAuthBegin-buf, 0); strncpy(pszMsg, buf, requestHeader.pszAuthBegin-buf); pszMsg[requestHeader.pszAuthBegin-buf] = NULL; // TRACE(pszMsg); // send Authorization information to the second proxy sprintf(pszMsg, "%s:%s", pServer->m_Info.strUser, pServer->m_Info.strPasswd); pServer->Base64(pszMsg, pszCode); sprintf(content, "Proxy-Authorization: Basic %s==\r\n", pszCode); send(sckClient, content, strlen(content), 0); // TRACE(content); // send(sckClient, requestHeader.pszAuthBegin, requestHeader.pszAuthEnd-requestHeader.pszAuthBegin, 0); strncpy(pszMsg, requestHeader.pszAuthBegin, requestHeader.pszAuthEnd-requestHeader.pszAuthBegin); pszMsg[requestHeader.pszAuthBegin, requestHeader.pszAuthEnd-requestHeader.pszAuthBegin] = NULL; // TRACE(pszMsg); // send the rest information send(sckClient, requestHeader.pszAuthEnd, strlen(requestHeader.pszAuthEnd), 0); iRet = 1; while(dwTotal<requestHeader.dwContSize && iRet) { iRet = recv(pThreadParam->sckClient, buf, BUFFER_SIZE, 0); buf[iRet] = NULL; if(iRet==SOCKET_ERROR) { sprintf(pszMsg, "while(nTotal<requestHeader.dwContSize && iRet) recv()=SOCKET_ERROR, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); goto _ThreadExit; } if(iRet) { pServer->OUTPUT(pServer,"_DEBUG_PRE_\t"); pServer->OUTPUT(pServer,buf); send(sckClient, buf, iRet, 0); dwTotal += iRet; } } // TRACE(requestHeader.pszAuthEnd); // waiting for response from server iRet = pServer->RecvHeader(pServer,sckClient, buf, BUFFER_SIZE, &httpHeader); send(pThreadParam->sckClient, buf, iRet, 0); if(httpHeader.dwContSize==0) { goto _ThreadExit; } dwTotal = iRet-(httpHeader.pContBegin - buf); while(dwTotal<httpHeader.dwContSize && iRet) { iRet = recv(sckClient, buf, BUFFER_SIZE, 0); if(iRet==SOCKET_ERROR) { sprintf(pszMsg, "recv()=SOCKET_ERROR, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError()); pServer->OUTPUT(pServer,pszMsg); goto _ThreadExit; } dwTotal += iRet; send(pThreadParam->sckClient, buf, iRet, 0); } _ThreadExit: pServer->OUTPUT(pServer,"Working thread terminated.\r\n"); closesocket(sckClient); closesocket(pThreadParam->sckClient); _ThreadExit1: WaitForSingleObject(pServer->m_hConnectionCount, INFINITE); pServer->m_nConnectionCount--; ReleaseSemaphore(pServer->m_hConnectionCount, 1, NULL); delete pThreadParam; return 0; } int CProxyServer::RecvRequest(CProxyServer* pServer,SOCKET sck, char *buf, DWORD dwSize, REQUESTHEADER *pRequestHeader) { char * pEnd, pszCode[32], pszText[32], *pAuthorization, *pRange, *pSize; int iRet; DWORD nTotal; pRequestHeader->dwFlag = REQUEST_UNAUTHORIZED; memset(buf, 0, dwSize); nTotal = 0; do{ iRet = recv(sck, buf+nTotal, dwSize-nTotal-1, 0); if(iRet==SOCKET_ERROR) { return SOCKET_ERROR; } nTotal += iRet; buf[nTotal] = NULL; pEnd = strstr(buf, "\r\n\r\n"); if(pEnd) { pAuthorization = strstr(buf, "Proxy-Authorization: "); if(!pAuthorization) { pRequestHeader->pszUserPass[0] = NULL; return 0; } sscanf(pAuthorization+21, "%*s%s", pszCode); Unbase64(pServer,pszText, pszCode); if(strcmp(pszText, "user:ag")) { strcpy(pRequestHeader->pszUserPass, pszText); return 0; } else pRequestHeader->dwFlag = 0; pRequestHeader->pszAuthBegin = pAuthorization; pRequestHeader->pszAuthEnd = strstr(pAuthorization, "\r\n")+2; pRequestHeader->pszVirtualRes = strstr(buf, "GET "); //"http://www.personalproxy.com/"); if(pRequestHeader->pszVirtualRes) { if(!strncmp(pRequestHeader->pszVirtualRes+4, "http://www.personalproxy.com", 28)) { pRequestHeader->dwFlag |= VIRTUAL_RESOURCE; sscanf(pRequestHeader->pszVirtualRes+4, "%s", pRequestHeader->pszUrl); } } pRange = strstr(buf, "RANGE: bytes"); if(pRange) { pRange = strstr(pRange, "="); if(pRange) { sscanf(pRange+1, "%d", &pRequestHeader->dwRange); pRequestHeader->dwFlag |= PARTIAL_CONTENT; } } pSize = strstr(buf, "Content-Length: "); if(pSize) { sscanf(pSize+16, "%d", &pRequestHeader->dwContSize); } else pRequestHeader->dwContSize = 0; pRequestHeader->pszContBegin = pEnd+4; return nTotal; } }while(!pEnd && iRet); return 0; } void CProxyServer::HttpService(CProxyServer* pServer,char *pszUrl, SOCKET sck, char *buf, REQUESTHEADER *pRequestHeader) { CString strServer, strObject; DWORD dwService, dwSize, dwFileLen; unsigned short nPort; int iRet; char pszFile[512], pszLine[512], pszType[16]; char pszCommand[128], *pQuestionMark; FILE* pFileContent; AfxParseURL(pszUrl, dwService, strServer, strObject, nPort); if(strObject == "/") sprintf(pszFile, "%s%s", SITEBASE, "\\VirtualPage.html"); else sprintf(pszFile, "%s%s", SITEBASE, strObject); UnCh(pServer,pszFile); // dwService 3 // nPort 80 // + strObject {"/count.dll?a=1&b=2"} // + strServer {"www.ms.com"} // + this 0x0012fe74 {CTryDlg hWnd=0x01460920} if(strstr(pszFile, "myextension")) { pQuestionMark = strstr(pszFile, "?"); if(pQuestionMark) { strcpy(pszCommand, pQuestionMark+1); *pQuestionMark = NULL; } else * pszCommand = NULL; HMODULE hModule = LoadLibrary(pszFile); if(!hModule) { pServer->OUTPUT(pServer,"requested file not found\r\n"); strcpy(buf, "HTTP/1.1 404 Not Found\r\nTransfer-encoding: chunked\r\nContent-type: text/html\r\n\r\n<HTML><H1>File not found</H1></HTML>"); send(sck, buf, strlen(buf), 0); return; } ProCommand = (int(*)(unsigned int, char*, char*))::GetProcAddress(hModule, "ProcessCommand"); if(!ProCommand) { pServer->OUTPUT(pServer,"ProcessCommand==NULL\r\n"); FreeLibrary(hModule); return; } ProCommand(sck, pszCommand, buf); FreeLibrary(hModule); return; } pFileContent = fopen(pszFile, "rb"); if(!pFileContent) { pServer->OUTPUT(pServer,"requested file not found\r\n"); strcpy(buf, "HTTP/1.1 404 Not Found\r\nTransfer-encoding: chunked\r\nContent-type: text/html\r\n\r\n<HTML><H1>File not found</H1></HTML>"); send(sck, buf, strlen(buf), 0); return; } dwFileLen = _filelength(_fileno(pFileContent)); if(pRequestHeader->dwFlag & PARTIAL_CONTENT) { strcpy(buf, "HTTP/1.1 206 Partial Content\r\n"); strcat(buf, "Accept-ranges: bytes\r\n"); dwSize = dwFileLen - pRequestHeader->dwRange; sprintf(pszLine, "Content-range: bytes %d-%d/%d\r\n", pRequestHeader->dwRange, dwFileLen-1, dwFileLen); strcat(buf, pszLine); fseek(pFileContent, pRequestHeader->dwRange, SEEK_SET); } else { strcpy(buf, "HTTP/1.1 200 OK\r\n"); dwSize = dwFileLen; } sprintf(pszLine, "Content-length: %d\r\n", dwSize); strcat(buf, pszLine); strcpy(pszLine, "Proxy-agent: Ag-PersonalProxy/1.0\r\n"); strcat(buf, pszLine); pServer->ContentType(pszFile, pszType); sprintf(pszLine, "Content-type: %s\r\n", pszType); strcat(buf, pszLine); strcat(buf, "\r\n"); send(sck, buf, strlen(buf), 0); while(!feof(pFileContent)) { dwSize = fread(buf, 1, BUFFER_SIZE, pFileContent); iRet = send(sck, buf, dwSize, 0); if(iRet == SOCKET_ERROR) break; } fclose(pFileContent); return; } void CProxyServer::Base64(char *pszSource, char *pszCode) { BYTE ot; int i; i=0; while(pszSource[i]) { ot = (0xFC & pszSource[i])>>2; *pszCode = Table(ot); i++; pszCode++; if(!pszSource[i]) { ot = (0x03 & pszSource[i-1])<<4; *pszCode = Table(ot); pszCode++; break; } ot = (0x03 & pszSource[i-1])<<4 | (0xF0 & pszSource[i])>>4; *pszCode = Table(ot); pszCode++; i++; if(!pszSource[i]) { ot = (0x0F & pszSource[i-1])<<2; *pszCode = Table(ot); pszCode++; break; } ot = (0x0F & pszSource[i-1])<<2 | (0xC0 & pszSource[i])>>6; *pszCode = Table(ot); pszCode++; ot = 0x3F & pszSource[i]; *pszCode = Table(ot), i++; pszCode++; } *pszCode = NULL; } DWORD CProxyServer::RecvHeader(CProxyServer* pServer,SOCKET socket, char *buf, DWORD dwSize, HTTPHEADER *pHeader) { char * pEnd, *pSize, *pType, *pLocation; int nRet, nTotal; memset(pHeader, 0, sizeof(HTTPHEADER)); nTotal = 0; do{ nRet = recv(socket, buf+nTotal, dwSize-nTotal, 0); if(nRet==SOCKET_ERROR)return SOCKET_ERROR; nTotal += nRet; buf[nRet] = NULL; pEnd = strstr(buf, "\r\n\r\n"); if(pEnd) { pSize = strstr(buf, "Content-length: "); if(pSize)sscanf(pSize+16, "%ud", &(pHeader->dwContSize)); else pHeader->dwContSize = -1; if(DWORD(pEnd-buf+4)<dwSize) pHeader->pContBegin = pEnd+4; else pHeader->pContBegin = NULL; sscanf(buf, "HTTP/%d.%d %d %s", &pHeader->nVerMajor, &pHeader->nVerMinor, &pHeader->dwHttpStatus, pHeader->pszStatus); pType = strstr(buf, "Content-type: "); if(pType)sscanf(pType+14, "%s", &(pHeader->pszType)); pLocation = strstr(buf, "Location: "); if(pLocation)sscanf(pLocation+10, "s", &(pHeader->pszLocation)); return nTotal; } }while(!pEnd && nRet); return nTotal; } void CProxyServer::Unbase64(CProxyServer* pServer,char *pszText, char *pszCode) { int nLen, i; BYTE bySixBits0, bySixBits1, bySixBits2, bySixBits3, c; nLen = strlen(pszCode); for(i=0; i<nLen; ) { bySixBits0 = GetSixBits(pszCode, i); if(i<nLen)bySixBits1 = GetSixBits(pszCode, i); if(i<nLen)bySixBits2 = GetSixBits(pszCode, i); if(i<nLen)bySixBits3 = GetSixBits(pszCode, i); c = bySixBits0<<2 | bySixBits1>>4; *pszText = c; pszText++; c = bySixBits1<<4 | bySixBits2>>2; *pszText = c; pszText++; c = bySixBits2<<6 | bySixBits3; *pszText = c; pszText++; } *pszText = NULL; } void CProxyServer::UnCh(CProxyServer* pServer,char *pszStr) { char pszLine[512]; int i, j, nLen; BYTE b1, b2; i=0; j=0; nLen = strlen(pszStr); while(i<nLen) { if(pszStr[i]=='%') { i++; sscanf(pszStr+i, "%2X", &b1); i += 2; } else { pszLine[j++] = pszStr[i++]; continue; } if(i>=nLen) { pszLine[j++] = b1; break; } if(pszStr[i]=='%') { i++; sscanf(pszStr+i, "%2X", &b2); i += 2; pszLine[j++] = b2; pszLine[j++] = b1; } else { pszLine[j++] = b1; pszLine[j++] = pszStr[i++]; } } pszLine[j]=0; strcpy(pszStr, pszLine); } void CProxyServer::ContentType(char *pszFile, char *pszType) { char drive[4], dir[MAX_PATH], fname[MAX_PATH], ext[16]; _splitpath(pszFile, drive, dir, fname, ext); _strlwr(ext); if(strstr(pszFile, "multipart")) strcpy(pszType, "multipart/mixed"); else if(!*ext) strcpy(pszType, "text/html"); else if(!strcmp(ext, ".jpg")) strcpy(pszType, "image/jpeg"); else if(!strcmp(ext, ".jpeg")) strcpy(pszType, "image/gif"); else if(!strcmp(ext, ".htm")) strcpy(pszType, "text/html"); else if(!strcmp(ext, ".html")) strcpy(pszType, "text/html"); else if(!strcmp(ext, ".zip")) strcpy(pszType, "application/x-compressed"); else if(!strcmp(ext, ".mpeg")) strcpy(pszType, "video/mpeg"); else strcpy(pszType, "application/octet-stream"); } BYTE CProxyServer::Table(BYTE ot) { if(ot>=0 && ot<=25)return 'A' + ot; else if(ot>=26 && ot<=51)return 'a' + (ot-26); else if(ot>=52 && ot<=61)return '0' + (ot-52); else if(ot==62)return '+'; else if(ot==63)return '/'; else return '='; } BYTE CProxyServer::GetSixBits(char *pszStr, int &i) { char c; while(1) { if(i>=(int)strlen(pszStr))break; c = pszStr[i++]; if(isupper(c)) return c-'A'; else if(islower(c)) return c-'a'+26; else if(isdigit(c)) return c-'0'+52; else if(c=='+') return 62; else if(c=='/') return 63; else if(c=='=') return 0; } return 0; }